iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 27
0
自我挑戰組

非本科之30天Ruby / Rails學習筆記系列 第 27

Day27: Rails關心你的胖Model - concern

  • 分享至 

  • xImage
  •  


圖片來源

在controller寫方法時,若常常需要用到某個方法,我們會將方法直接寫在Model或上層的application_controller.rb來取用。

已正在進行的專案為例,每個User有一台購物車,除了devise給我們現有的current_user之外,我想在寫個current_cart給每個controller用,此時就可以把定義current_cart的方法寫在application_controller.rb

class ApplicationController < ActionController::Base

  private
  def current_cart
    @current_cart ||= Cart.find_or_create_by(user: current_user)
  end
end

但有時候並不是每個controller或Model都需要用到這個方法,尤其是把所有要用的方法寫在該類別的Model,會導致Model越來越肥,controller越來越瘦。

有需要的時候再拿進來

為了解決這個問題,rails在models下有個資料夾名稱concerns,把定義方法寫在這,在該controller有需要的時候再引入使用就好。

新增一個檔案 usercart.rb

  module Usercart
    extend ActiveSupport::Concern

    included do
      has_one :cart
    end

    module ClassMethods
      def search(search)
        if search
          where(['title || description || address LIKE ?', "%#{search}%"])
        else
          all
        end
      end
    end

    private
    def current_cart
      @current_cart ||= Cart.find_or_create_by(user: current_user)
    end

  end

included do ...end 當這個module被include到Model時會做的事:(一對一)有一台購物車
ClassMethod 在這裡定義的方法被include時會變成類別方法:可以直接針對該Model做搜尋的方法。
current_cart 被include之後會變成該類別的實體方法:如果有找到車就用這台,沒有車就生一台給user。

此時在User的Model加入:

class User < ApplicationRecord
    include Usercart
end

就可以擁有在concern資料夾下內 usercart.rb 裡的方法可以用了,相對的如果你在其他的Model也想要用的話,再直接include進該Model就好。

參考資料:
How to use concerns in Rails 4
Rails 程式碼整理術(入門)

“Live today. Not yesterday. Not tomorrow. Inhabit your moments. Don’t rent them out to tomorrow.”

– Jerry Spinelli, Writer

本文同步發佈於: https://louiswuyj.tw/


上一篇
Day26: Rails中的view_helper
下一篇
Day28: 用個Github來版本控制吧
系列文
非本科之30天Ruby / Rails學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

我要留言

立即登入留言